package Estructuras;

public class task_list {
    public nodo head;
   
    public task_list(){
        head = null;
    }
 
    // Se inserta hacia adelante y el nuevo nodo es la cabeza
    // de la lista
    public synchronized void Insert(Task_struct pcb){
        nodo aux = this.head;
        nodo npcb = new nodo(pcb);
        
        if (isEmpty()){
            head = npcb;
            head.Next = null;
            head.Prev = null;
	    head.tam = 1;
        }else{
           aux.Prev = npcb; 
           npcb.Next = aux;
           npcb.Prev = null;
           int tamano = head.tam;
           tamano++;
           head = head.Prev;
           head.tam = tamano;
       }
    }
    
 public synchronized void Remove(int pid){
     if (isEmpty()){
            return;
        }else{
	    nodo aux = this.head;
            if( aux.Pcb.getPid() == pid){
                if(head.tam == 1){
                    head = null;
                }else{
                    head = head.Next;
                }
	    }else{
                while(aux.Next != null){
                    if(aux.Pcb.getPid() == pid){
                        int valor = aux.tam;
                        nodo temp;
                        temp = aux.Next;
                        temp.Prev = aux.Prev;
                        aux.Prev.Next = temp;                         
                        head.tam--;
                        nodo temp2 = head.Next;
                        while(temp2.tam != valor - 1){
                            temp2.tam--;
                            temp2 = temp2.Next;
                        }
                        return;                   
                    }
                    aux = aux.Next;
                }
                //ultimo de la lista
                if(aux.Pcb.getPid() == pid){
                     int valor = aux.tam;
                     aux.Prev.Next = null;                        
                      nodo temp = head;
                      while(temp.Next != null){
                        temp.tam --;
                        temp = temp.Next;
                      }
                      temp.tam --;
                      return;                   
                }
            }
       }
    }
 
    public synchronized void Print(){
        
        if (isEmpty()){
            System.out.println("Vacia");
		return;
        }else{
            nodo aux = this.head;
            int j = head.tam;
            while(j != 0){
                System.out.println("valores " + aux.getPcb().getPid());
                System.out.println("tam " + aux.tam);
                aux = aux.Next;
		j--;
            }
        }
    }
    public boolean isEmpty(){
        return this.head == null;
    }



  public nodo getHead() {
    return head;
  }

  public int size(){

      if (isEmpty()){
          return 0;
      }
      return this.head.tam;
  }

  /*
  public void append(task_list t2){

      if (isEmpty()){
          this.head = t2.getHead();

      }else{

          int newsize = t2.size() + this.head.tam;
          nodo head_t2 = t2.getHead();
          this.head.Prev.Next = head_t2;
          head_t2.Prev.Next = this.head;
          this.head.tam = newsize;
      }
      
  }
*/

   public void recorrerTaskList(Scheduler sche){
      Task_struct ts;
      if(!isEmpty()){
         nodo head;
         head = this.getHead();
         if(head == null)
              return;
         int tam = head.tam;
         System.out.println("Buscando procesos no agregados y muertos");
         while(tam!= 0){
              //solicito el task list
              ts = head.getPcb();
              //no ha sido agregado al Scheduller y estado no es wait
              if(ts.getSC() == null){
                  //lo agrega al sche uler
                  sche.enqueue_task(ts);
              }
              //Verificar si el nodo fue marcado para ser eliminado
              switch(ts.getState()){
                case Task_struct.TERMINATED:
                  //se elimina de la lista
                  this.Remove(ts.getPid());
                  System.out.println("Eliminando pid="+ts.getPid());
                  break;
                case Task_struct.BLOCKED:
                  //actualiza espera por IO
                  break;
                default:
              }
              if(head == null)
                   return;
              head = head.getNext();
              tam--;

         }
      }
    }
}


